package com.zhangxi.websqlit.file.service.impl;



import com.zhangxi.websqlit.common.util.FileUtil;
import com.zhangxi.websqlit.file.entity.SearchFileInfoEntity;
import com.zhangxi.websqlit.file.repository.FileInfoDao;
import com.zhangxi.websqlit.file.service.FileInfoService;
import com.zhangxi.websqlit.mybatis.entity.PtFileEntity;
import com.zhangxi.websqlit.mybatis.flexigrid.PadingRstType;
import com.zhangxi.websqlit.mybatis.flexigrid.PagingBean;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;

@Service
public class FileInfoServiceImpl implements FileInfoService {
    private Logger logger = LogManager.getLogger(this.getClass());
    private final static String BOOT_DIR = "-1";
    private final static Integer FILE_TYPE_DIR = 1;
    private final static String FILE_SEPARATOR = "/";
    @Value(value = "${base.dir}")
    private String baseDir;
    @Resource
    private FileInfoDao fileInfoDao;

    public String getFilePathById(String fileUuid){
        PtFileEntity ptFileEntity =  fileInfoDao.queryFileInfoById(fileUuid);
        if(ptFileEntity == null){
            return "";
        }
        return ptFileEntity.getFilePath();
    }

    @Override
    public String uploadFile(String fileName, InputStream inputStream, String parentUuid) {
        String fileUuid= FileUtil.getUUID();
        baseDir = FileUtil.mkdirNoExit(baseDir);
        logger.info(baseDir);
        String parentDir = "";
        String fileDir= baseDir;
        //如果父目录不是根目录，获取父目录
        if(!BOOT_DIR.equals(parentUuid)){
            parentDir = getFilePathById(parentUuid);
            fileDir = baseDir + FILE_SEPARATOR + parentDir;
            fileDir = FileUtil.mkdirNoExit(fileDir);
            logger.info(fileDir);
        }
        int fileSize = FileUtil.saveFile(fileDir + FILE_SEPARATOR + fileName,inputStream);
        String filePath = parentDir + FILE_SEPARATOR + fileName;
        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoByPath(filePath);
        if(ptFileEntity == null){
            ptFileEntity = new PtFileEntity();
            ptFileEntity.setFileUuid(fileUuid);
            ptFileEntity.setFileCapacity(fileSize+"");
            ptFileEntity.setFilePath(filePath);
            ptFileEntity.setFileName(fileName);
            ptFileEntity.setParentUuid(parentUuid);
            fileInfoDao.insertIntoFileInfo(ptFileEntity);
        }else{
            fileUuid = ptFileEntity.getFileUuid();
            ptFileEntity.setFileCapacity(fileSize+"");
            ptFileEntity.setFileName(fileName);
            fileInfoDao.updateIntoFileInfo(ptFileEntity);
        }
        return fileUuid;
    }

    @Override
    public PadingRstType<PtFileEntity> getFileListByPage(SearchFileInfoEntity entity, PagingBean paging) {
        paging.dealSortName(PtFileEntity.class);
        PadingRstType<PtFileEntity> padingRstType = new PadingRstType<>();
        padingRstType.setPage(paging.getPage());
        List<PtFileEntity> ptFileEntities = fileInfoDao.queryFileInfoListByPage(entity,paging);
        int total = fileInfoDao.queryFileInfoTotal(entity);
        padingRstType.setRawRecords(ptFileEntities);
        padingRstType.setTotal(total);
        padingRstType.putItems();
        return padingRstType;
    }

    @Override
    public String mkdir(PtFileEntity entity) {
        String uuid = FileUtil.getUUID();
        String parentUuid = entity.getParentUuid();
        String fileName = entity.getFileName();
        String parentDir = "";
        String fileDir= baseDir;
        //如果父目录不是根目录，获取父目录
        if(!BOOT_DIR.equals(parentUuid)){
            parentDir = getFilePathById(parentUuid);
            fileDir = baseDir + FILE_SEPARATOR + parentDir;
        }
        String dir = FileUtil.mkdirNoExit(fileDir + FILE_SEPARATOR + fileName);
        logger.info("dir:" + dir);
        String filePath = parentDir + FILE_SEPARATOR + fileName;
        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoByPath(filePath);
        if(ptFileEntity == null){
            ptFileEntity = new PtFileEntity();
            ptFileEntity.setFileUuid(uuid);
            ptFileEntity.setFilePath(filePath);
            ptFileEntity.setFileName(fileName);
            ptFileEntity.setParentUuid(parentUuid);
            ptFileEntity.setFileType(FILE_TYPE_DIR);
            ptFileEntity.setFileCapacity("0");
            fileInfoDao.insertIntoFileInfo(ptFileEntity);
        }else{
            uuid = ptFileEntity.getFileUuid();
        }
        return uuid;
    }

    @Override
    public String queryFileInfoById(String fileUuid) {
        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoById(fileUuid);
        if(ptFileEntity == null){
            return FILE_SEPARATOR;
        }
        return ptFileEntity.getFilePath() + FILE_SEPARATOR;
    }

    @Override
    public PtFileEntity queryFileParentById(String fileUuid) {
        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoById(fileUuid);
        if(ptFileEntity == null || BOOT_DIR.equals(ptFileEntity.getParentUuid())){
            ptFileEntity = new PtFileEntity();
            ptFileEntity.setFilePath(FILE_SEPARATOR);
            ptFileEntity.setFileUuid(BOOT_DIR);
            return ptFileEntity;
        }
        return fileInfoDao.queryFileInfoById(ptFileEntity.getParentUuid());
    }

    @Override
    public ResponseEntity<byte[]> download(String fileUuId) {

        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoById(fileUuId);
        if(ptFileEntity == null){
            return null;
        }
        byte[] contents = downloadFile(ptFileEntity);
        HttpHeaders headers =
                new HttpHeaders();
        String fileName= ptFileEntity.getFileName();
        try {
            fileName = new  String(fileName.getBytes( "utf-8" ),"ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        headers.setContentDispositionFormData("attachment"
                ,fileName
                );//告知浏览器以下载方式打开
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置MIME类型

        return new ResponseEntity<byte[]>(
                contents,
                headers,
                HttpStatus.OK);
    }



    @Override
    public List<PtFileEntity> queryFileList() {
        return fileInfoDao.queryFileList();
    }

    @Override
    public ResponseEntity<byte[]> downloadPhone(String fileUUId) {
        PtFileEntity ptFileEntity = fileInfoDao.queryFileInfoById(fileUUId);
        if(ptFileEntity == null){
            return null;
        }
        byte[] contents = downloadFile(ptFileEntity);
        HttpHeaders headers =
                new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置MIME类型

        return new ResponseEntity<byte[]>(
                contents,
                headers,
                HttpStatus.OK);
    }

    /**
     * 下载文件
     * @param ptFileEntity
     * @return
     */
    private byte[] downloadFile(PtFileEntity ptFileEntity) {
        byte[] contents = null;
        try(
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                FileInputStream fileInputStream = new FileInputStream(baseDir + FILE_SEPARATOR + ptFileEntity.getFilePath());
        ) {
            FileUtil.copyStream(byteArrayOutputStream,fileInputStream);
            contents = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return contents;
    }
}
